#pragma once
# include<Arduino.h>
# include<ArduinoJson.h>
# include "global.hpp"

const String SOURCE = "SOURCE";
const String SOURCE_WEB = "SOURCE_WEB";

const String TARGET = "TARGET"; // $'target woker name' or BROCAST
const String TARGET_BROCAST = "BROCAST";

const String ACTION = "ACTION";
const String ARGS = "ARGS";
const String KW_ARGS = "KW_ARGS";

class Message {
    private:

    StaticJsonDocument<768> root;

    public:

    Message(const String &str) {
        deserializeJson(root, str);
    }

    Message(String source, String target, String action) {
        root[SOURCE] = source;
        root[TARGET] = target;
        root[ACTION] = action;
        root.createNestedArray(ARGS);
        root.createNestedObject(KW_ARGS);
    }

    Message(String target, String action) {
        new (this) Message(WORKER_NAME, target, action);
    }

    template<typename T>
    void add_arg(const T &value) {
        root[ARGS].add(value);
    }

    template<typename T>
    void add_kv(const String key, const T &value) {
        root[KW_ARGS][key] = value;
    }

    template<typename T>
    T get(const String &key) {
        return root[key];
    }

    String to_string() {
        String str;
        serializeJson(root, str);
        return str;
    }

    void print() {
        Serial.println("message body:");
        serializeJsonPretty(root, Serial);
        Serial.println("");
    }
};
